//
// Created by ly-zhouxyi on 2024/3/5.
//

#ifndef FFMPEGPLAYER_AUDIODECODER_H
#define FFMPEGPLAYER_AUDIODECODER_H

#include "DataQueue.h"
#include "PlayStatus.h"
#include "FFmpegCallJava.h"
#include "SoundTouch.h"
#include "AudioDecoder.h"

extern "C"
{
#include "libavcodec/avcodec.h"
#include <libswresample/swresample.h>
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
};

class AudioDecoder {
public:
    FFmpegCallJava *callJava = NULL;
    PlayStatus *playStatus = NULL;
    AVCodecContext *avCodecContext = NULL;
    AVCodecParameters *avCodecParameters = NULL;
    DataQueue *audioQueue = NULL;
    pthread_t thread_audio_play;
    uint8_t *buffer = NULL;
    unsigned int buffer_size;
    int streamIndex = -1;  // 音频索引
    int sample_rate = 0;
    int duration = 0;
    AVRational time_base; // 时间单位         总时间/帧数   单位时间     *   时间戳= pts  * 总时间/帧数   h264    记录int  位数最小化   单位    帧率
    double now_time;//当前frame时间
    double clock;//当前播放的时间    准确时间
    double last_time; //上一次调用时间
    int data_size = 0;
    int newSamples; // 转换后的波的数量
    uint8_t *outBuffer = NULL; // 输出
    /***********************************************************/
    // 音频处理 SoundTouch
    soundtouch::SoundTouch *soundTouch = NULL;
    // 新的缓冲区
    soundtouch::SAMPLETYPE  *newSampleBuffer = NULL;
    // 节拍 大快小慢
    float speed = 1.0f;
    // 音调
    float pitch = 1.0f;
    /***********************************************************/
    // OpenSL ES 播放音频
    // 引擎接口
    SLObjectItf engineObject = NULL;
    SLEngineItf engineEngine = NULL;
    //混音器
    SLObjectItf outputMixObject = NULL;
    SLEnvironmentalReverbItf outputMixEnvironmentalReverb = NULL;
    SLEnvironmentalReverbSettings reverbSettings = SL_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR;
    //pcm
    SLObjectItf pcmPlayerObject = NULL;
    SLPlayItf pcmPlayerPlay = NULL;
    SLVolumeItf pcmVolumePlay = NULL;
    SLMuteSoloItf pcmMutePlay = NULL;
    //缓冲器队列接口
    SLAndroidSimpleBufferQueueItf pcmBufferQueue = NULL;
    AVPacket *avPacket = NULL;
    AVFrame *avFrame = NULL;

    bool isSync = false;
    int dataSize;
    int num;


    AudioDecoder(FFmpegCallJava *callJava, PlayStatus *playStatus, int sampleRate);

    void play();

    void pause();

    void resume();

    void release();

    void setVolume(float volume);

    void setSpeed(float speed);

    void setPitch(float pitch);

    void setMute(int channel);

    void setVolumeMute(bool mute);

    int getCurrentVolume();

    int getSoundTouchData();

    void initOpenSLES();

    int getCurrentSampleRateForOpenSlEs(int sample_rate);

    int getAudioBuffer(void **pcmBuffer);

    ~AudioDecoder();
};


#endif //FFMPEGPLAYER_AUDIODECODER_H
